Micron Document
🎖️GitЯра🎖️

Node / meshtastic / Meshtastic-Android / files / app / src / fdroid / java / com / geeksville / mesh / model / map / clustering / MarkerClusterer.java

Displaying Raw • Download

app/src/fdroid/java/com/geeksville/mesh/model/map/clustering/MarkerClusterer.java ui_message_list (be3f882f) Text, 6.56 KB

T8b949e/*
* Copyright (c) 2025 Meshtastic LLC
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/

Tff7b72package T7ee787com.geeksville.mesh.model.map.clusteringTb4b4b4;

Tff7b72import T7ee787android.graphics.BitmapTb4b4b4;
Tff7b72import T7ee787android.graphics.CanvasTb4b4b4;
Tff7b72import T7ee787android.graphics.PointTb4b4b4;
Tff7b72import T7ee787android.view.MotionEventTb4b4b4;

Tff7b72import T7ee787com.geeksville.mesh.model.map.MarkerWithLabelTb4b4b4;

Tff7b72import T7ee787org.osmdroid.util.BoundingBoxTb4b4b4;
Tff7b72import T7ee787org.osmdroid.views.MapViewTb4b4b4;
Tff7b72import T7ee787org.osmdroid.views.overlay.OverlayTb4b4b4;

Tff7b72import T7ee787java.util.ArrayListTb4b4b4;
Tff7b72import T7ee787java.util.IteratorTb4b4b4;
Tff7b72import T7ee787java.util.ListIteratorTb4b4b4;

T8b949e/**
* An overlay allowing to perform markers clustering.
* Usage: put your markers inside with add(Marker), and add the MarkerClusterer to the map overlays.
* Depending on the zoom level, markers will be displayed separately, or grouped as a single Marker. <br/>
*
* This abstract class provides the framework. Sub-classes have to implement the clustering algorithm,
* and the rendering of a cluster.
*
* @author M.Kergall
*
*/
Tff7b72public Tff7b72abstract Tff7b72class T56d364MarkerClusterer Tff7b72extends Te6edf3Overlay Tb4b4b4{

T8b949e/** impossible value for zoom level, to force clustering */
Tff7b72protected Tff7b72static Tff7b72final Tffa657int Te6edf3FORCE_CLUSTERING Tff7b72= Tff7b72-T79c0ff1Tb4b4b4;
Tff7b72protected Te6edf3ArrayListTff7b72<Te6edf3MarkerWithLabelTff7b72> Te6edf3mItems Tff7b72= Tff7b72new Te6edf3ArrayListTff7b72<Te6edf3MarkerWithLabelTff7b72>Tb4b4b4(Tb4b4b4)Tb4b4b4;
Tff7b72protected Te6edf3Point Te6edf3mPoint Tff7b72= Tff7b72new Te6edf3PointTb4b4b4(Tb4b4b4)Tb4b4b4;
Tff7b72protected Te6edf3ArrayListTff7b72<Te6edf3StaticClusterTff7b72> Te6edf3mClusters Tff7b72= Tff7b72new Te6edf3ArrayListTff7b72<Te6edf3StaticClusterTff7b72>Tb4b4b4(Tb4b4b4)Tb4b4b4;
Tff7b72protected Tffa657int Te6edf3mLastZoomLevelTb4b4b4;
Tff7b72protected Te6edf3Bitmap Te6edf3mClusterIconTb4b4b4;
Tff7b72protected Te6edf3String Te6edf3mNameTb4b4b4, Te6edf3mDescriptionTb4b4b4;
T8b949e// abstract methods:
T8b949e/** clustering algorithm */
Tff7b72public Tff7b72abstract Te6edf3ArrayListTff7b72<Te6edf3StaticClusterTff7b72> Td2a8ffclustererTb4b4b4(Te6edf3MapView Te6edf3mapViewTb4b4b4)Tb4b4b4;
T8b949e/** Build the marker for a cluster. */
Tff7b72public Tff7b72abstract Te6edf3MarkerWithLabel Td2a8ffbuildClusterMarkerTb4b4b4(Te6edf3StaticCluster Te6edf3clusterTb4b4b4, Te6edf3MapView Te6edf3mapViewTb4b4b4)Tb4b4b4;
T8b949e/** build clusters markers to be used at next draw */
Tff7b72public Tff7b72abstract Tffa657void Td2a8ffrendererTb4b4b4(Te6edf3ArrayListTff7b72<Te6edf3StaticClusterTff7b72> Te6edf3clustersTb4b4b4, Te6edf3Canvas Te6edf3canvasTb4b4b4, Te6edf3MapView Te6edf3mapViewTb4b4b4)Tb4b4b4;
Tff7b72public Td2a8ffMarkerClustererTb4b4b4(Tb4b4b4) Tb4b4b4{
Tff7b72superTb4b4b4(Tb4b4b4)Tb4b4b4;
Te6edf3mLastZoomLevel Tff7b72= Te6edf3FORCE_CLUSTERINGTb4b4b4;
Tb4b4b4}

Tff7b72public Tffa657void Td2a8ffsetNameTb4b4b4(Te6edf3String Te6edf3nameTb4b4b4)Tb4b4b4{
Te6edf3mName Tff7b72= Te6edf3nameTb4b4b4;
Tb4b4b4}
Tff7b72public Te6edf3String Td2a8ffgetNameTb4b4b4(Tb4b4b4)Tb4b4b4{
Tff7b72return Te6edf3mNameTb4b4b4;
Tb4b4b4}
Tff7b72public Tffa657void Td2a8ffsetDescriptionTb4b4b4(Te6edf3String Te6edf3descriptionTb4b4b4)Tb4b4b4{
Te6edf3mDescription Tff7b72= Te6edf3descriptionTb4b4b4;
Tb4b4b4}
Tff7b72public Te6edf3String Td2a8ffgetDescriptionTb4b4b4(Tb4b4b4)Tb4b4b4{
Tff7b72return Te6edf3mDescriptionTb4b4b4;
Tb4b4b4}
T8b949e/** Set the cluster icon to be drawn when a cluster contains more than 1 marker.
* If not set, default will be the default osmdroid marker icon (which is really inappropriate as a cluster icon). */
Tff7b72public Tffa657void Td2a8ffsetIconTb4b4b4(Te6edf3Bitmap Te6edf3iconTb4b4b4)Tb4b4b4{
Te6edf3mClusterIcon Tff7b72= Te6edf3iconTb4b4b4;
Tb4b4b4}
T8b949e/** Add the Marker.
* Important: Markers added in a MarkerClusterer should not be added in the map overlays. */
Tff7b72public Tffa657void Td2a8ffaddTb4b4b4(Te6edf3MarkerWithLabel Te6edf3markerTb4b4b4)Tb4b4b4{
Te6edf3mItemsTb4b4b4.Te6edf3addTb4b4b4(Te6edf3markerTb4b4b4)Tb4b4b4;
Tb4b4b4}
T8b949e/** Force a rebuild of clusters at next draw, even without a zooming action.
* Should be done when you changed the content of a MarkerClusterer. */
Tff7b72public Tffa657void Td2a8ffinvalidateTb4b4b4(Tb4b4b4)Tb4b4b4{
Te6edf3mLastZoomLevel Tff7b72= Te6edf3FORCE_CLUSTERINGTb4b4b4;
Tb4b4b4}
T8b949e/** @return the Marker at id (starting at 0) */
Tff7b72public Te6edf3MarkerWithLabel Td2a8ffgetItemTb4b4b4(Tffa657int Te6edf3idTb4b4b4)Tb4b4b4{
Tff7b72return Te6edf3mItemsTb4b4b4.Te6edf3getTb4b4b4(Te6edf3idTb4b4b4)Tb4b4b4;
Tb4b4b4}
T8b949e/** @return the list of Markers. */
Tff7b72public Te6edf3ArrayListTff7b72<Te6edf3MarkerWithLabelTff7b72> Td2a8ffgetItemsTb4b4b4(Tb4b4b4)Tb4b4b4{
Tff7b72return Te6edf3mItemsTb4b4b4;
Tb4b4b4}

Tff7b72protected Tffa657void Td2a8ffhideInfoWindowsTb4b4b4(Tb4b4b4)Tb4b4b4{
Tff7b72for Tb4b4b4(Te6edf3MarkerWithLabel Te6edf3m Tb4b4b4: Te6edf3mItemsTb4b4b4)Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3mTb4b4b4.Te6edf3isInfoWindowShownTb4b4b4(Tb4b4b4)Tb4b4b4)
Te6edf3mTb4b4b4.Te6edf3closeInfoWindowTb4b4b4(Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4}

Tf0883e@Override Tff7b72public Tffa657void Td2a8ffdrawTb4b4b4(Te6edf3Canvas Te6edf3canvasTb4b4b4, Te6edf3MapView Te6edf3mapViewTb4b4b4, Tffa657boolean Te6edf3shadowTb4b4b4) Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3shadowTb4b4b4)
Tff7b72returnTb4b4b4;
T8b949e//if zoom has changed and mapView is now stable, rebuild clusters:
Tffa657int Te6edf3zoomLevel Tff7b72= Te6edf3mapViewTb4b4b4.Te6edf3getZoomLevelTb4b4b4(Tb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3zoomLevel Tff7b72!Tff7b72= Te6edf3mLastZoomLevel Tff7b72&Tff7b72& Tff7b72!Te6edf3mapViewTb4b4b4.Te6edf3isAnimatingTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4{
Te6edf3hideInfoWindowsTb4b4b4(Tb4b4b4)Tb4b4b4;
Te6edf3mClusters Tff7b72= Te6edf3clustererTb4b4b4(Te6edf3mapViewTb4b4b4)Tb4b4b4;
Te6edf3rendererTb4b4b4(Te6edf3mClustersTb4b4b4, Te6edf3canvasTb4b4b4, Te6edf3mapViewTb4b4b4)Tb4b4b4;
Te6edf3mLastZoomLevel Tff7b72= Te6edf3zoomLevelTb4b4b4;
Tb4b4b4}
Tff7b72for Tb4b4b4(Te6edf3StaticCluster Te6edf3clusterTb4b4b4:Te6edf3mClustersTb4b4b4)Tb4b4b4{
Te6edf3MarkerWithLabel Te6edf3marker Tff7b72= Te6edf3clusterTb4b4b4.Te6edf3getMarkerTb4b4b4(Tb4b4b4)Tb4b4b4;
Te6edf3markerTb4b4b4.Te6edf3drawTb4b4b4(Te6edf3canvasTb4b4b4, Te6edf3mapViewTb4b4b4, Tff7b72falseTb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4}

Tff7b72public Te6edf3IterableTff7b72<Te6edf3StaticClusterTff7b72> Td2a8ffreversedClustersTb4b4b4(Tb4b4b4) Tb4b4b4{
Tff7b72return Tff7b72new Te6edf3IterableTff7b72<Te6edf3StaticClusterTff7b72>Tb4b4b4(Tb4b4b4) Tb4b4b4{
Tf0883e@Override
Tff7b72public Te6edf3IteratorTff7b72<Te6edf3StaticClusterTff7b72> Td2a8ffiteratorTb4b4b4(Tb4b4b4) Tb4b4b4{
Tff7b72final Te6edf3ListIteratorTff7b72<Te6edf3StaticClusterTff7b72> Te6edf3i Tff7b72= Te6edf3mClustersTb4b4b4.Te6edf3listIteratorTb4b4b4(Te6edf3mClustersTb4b4b4.Te6edf3sizeTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tff7b72return Tff7b72new Te6edf3IteratorTff7b72<Te6edf3StaticClusterTff7b72>Tb4b4b4(Tb4b4b4) Tb4b4b4{
Tf0883e@Override
Tff7b72public Tffa657boolean Td2a8ffhasNextTb4b4b4(Tb4b4b4) Tb4b4b4{
Tff7b72return Te6edf3iTb4b4b4.Te6edf3hasPreviousTb4b4b4(Tb4b4b4)Tb4b4b4;
Tb4b4b4}

Tf0883e@Override
Tff7b72public Te6edf3StaticCluster Td2a8ffnextTb4b4b4(Tb4b4b4) Tb4b4b4{
Tff7b72return Te6edf3iTb4b4b4.Te6edf3previousTb4b4b4(Tb4b4b4)Tb4b4b4;
Tb4b4b4}

Tf0883e@Override
Tff7b72public Tffa657void Td2a8ffremoveTb4b4b4(Tb4b4b4) Tb4b4b4{
Te6edf3iTb4b4b4.Te6edf3removeTb4b4b4(Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4}Tb4b4b4;
Tb4b4b4}
Tb4b4b4}Tb4b4b4;
Tb4b4b4}

Tf0883e@Override Tff7b72public Tffa657boolean Td2a8ffonSingleTapConfirmedTb4b4b4(Tff7b72final Te6edf3MotionEvent Te6edf3eventTb4b4b4, Tff7b72final Te6edf3MapView Te6edf3mapViewTb4b4b4)Tb4b4b4{
Tff7b72for Tb4b4b4(Tff7b72final Te6edf3StaticCluster Te6edf3cluster Tb4b4b4: Te6edf3reversedClustersTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3clusterTb4b4b4.Te6edf3getMarkerTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3onSingleTapConfirmedTb4b4b4(Te6edf3eventTb4b4b4, Te6edf3mapViewTb4b4b4)Tb4b4b4)
Tff7b72return Tff7b72trueTb4b4b4;
Tb4b4b4}
Tff7b72return Tff7b72falseTb4b4b4;
Tb4b4b4}
Tf0883e@Override Tff7b72public Tffa657boolean Td2a8ffonLongPressTb4b4b4(Tff7b72final Te6edf3MotionEvent Te6edf3eventTb4b4b4, Tff7b72final Te6edf3MapView Te6edf3mapViewTb4b4b4) Tb4b4b4{
Tff7b72for Tb4b4b4(Tff7b72final Te6edf3StaticCluster Te6edf3cluster Tb4b4b4: Te6edf3reversedClustersTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3clusterTb4b4b4.Te6edf3getMarkerTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3onLongPressTb4b4b4(Te6edf3eventTb4b4b4, Te6edf3mapViewTb4b4b4)Tb4b4b4)
Tff7b72return Tff7b72trueTb4b4b4;
Tb4b4b4}
Tff7b72return Tff7b72falseTb4b4b4;
Tb4b4b4}

Tf0883e@Override Tff7b72public Tffa657boolean Td2a8ffonTouchEventTb4b4b4(Tff7b72final Te6edf3MotionEvent Te6edf3eventTb4b4b4, Tff7b72final Te6edf3MapView Te6edf3mapViewTb4b4b4) Tb4b4b4{
Tff7b72for Tb4b4b4(Te6edf3StaticCluster Te6edf3cluster Tb4b4b4: Te6edf3reversedClustersTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3clusterTb4b4b4.Te6edf3getMarkerTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3onTouchEventTb4b4b4(Te6edf3eventTb4b4b4, Te6edf3mapViewTb4b4b4)Tb4b4b4)
Tff7b72return Tff7b72trueTb4b4b4;
Tb4b4b4}
Tff7b72return Tff7b72falseTb4b4b4;
Tb4b4b4}

Tf0883e@Override Tff7b72public Tffa657boolean Td2a8ffonDoubleTapTb4b4b4(Tff7b72final Te6edf3MotionEvent Te6edf3eventTb4b4b4, Tff7b72final Te6edf3MapView Te6edf3mapViewTb4b4b4) Tb4b4b4{
Tff7b72for Tb4b4b4(Tff7b72final Te6edf3StaticCluster Te6edf3cluster Tb4b4b4: Te6edf3reversedClustersTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3clusterTb4b4b4.Te6edf3getMarkerTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3onDoubleTapTb4b4b4(Te6edf3eventTb4b4b4, Te6edf3mapViewTb4b4b4)Tb4b4b4)
Tff7b72return Tff7b72trueTb4b4b4;
Tb4b4b4}
Tff7b72return Tff7b72falseTb4b4b4;
Tb4b4b4}

Tf0883e@Override Tff7b72public Te6edf3BoundingBox Td2a8ffgetBoundsTb4b4b4(Tb4b4b4)Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3mItemsTb4b4b4.Te6edf3sizeTb4b4b4(Tb4b4b4) Tff7b72=Tff7b72= T79c0ff0Tb4b4b4)
Tff7b72return Tff7b72nullTb4b4b4;
Tffa657double Te6edf3minLat Tff7b72= Te6edf3DoubleTb4b4b4.Te6edf3MAX_VALUETb4b4b4;
Tffa657double Te6edf3minLon Tff7b72= Te6edf3DoubleTb4b4b4.Te6edf3MAX_VALUETb4b4b4;
Tffa657double Te6edf3maxLat Tff7b72= Tff7b72-Te6edf3DoubleTb4b4b4.Te6edf3MAX_VALUETb4b4b4;
Tffa657double Te6edf3maxLon Tff7b72= Tff7b72-Te6edf3DoubleTb4b4b4.Te6edf3MAX_VALUETb4b4b4;
Tff7b72for Tb4b4b4(Tff7b72final Te6edf3MarkerWithLabel Te6edf3item Tb4b4b4: Te6edf3mItemsTb4b4b4) Tb4b4b4{
Tff7b72final Tffa657double Te6edf3latitude Tff7b72= Te6edf3itemTb4b4b4.Te6edf3getPositionTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3getLatitudeTb4b4b4(Tb4b4b4)Tb4b4b4;
Tff7b72final Tffa657double Te6edf3longitude Tff7b72= Te6edf3itemTb4b4b4.Te6edf3getPositionTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3getLongitudeTb4b4b4(Tb4b4b4)Tb4b4b4;
Te6edf3minLat Tff7b72= Te6edf3MathTb4b4b4.Te6edf3minTb4b4b4(Te6edf3minLatTb4b4b4, Te6edf3latitudeTb4b4b4)Tb4b4b4;
Te6edf3minLon Tff7b72= Te6edf3MathTb4b4b4.Te6edf3minTb4b4b4(Te6edf3minLonTb4b4b4, Te6edf3longitudeTb4b4b4)Tb4b4b4;
Te6edf3maxLat Tff7b72= Te6edf3MathTb4b4b4.Te6edf3maxTb4b4b4(Te6edf3maxLatTb4b4b4, Te6edf3latitudeTb4b4b4)Tb4b4b4;
Te6edf3maxLon Tff7b72= Te6edf3MathTb4b4b4.Te6edf3maxTb4b4b4(Te6edf3maxLonTb4b4b4, Te6edf3longitudeTb4b4b4)Tb4b4b4;
Tb4b4b4}
Tff7b72return Tff7b72new Te6edf3BoundingBoxTb4b4b4(Te6edf3maxLatTb4b4b4, Te6edf3maxLonTb4b4b4, Te6edf3minLatTb4b4b4, Te6edf3minLonTb4b4b4)Tb4b4b4;
Tb4b4b4}

Tb4b4b4}

Served by rngit 1.5.1 - Generated in 0.07s